package com.example.orderserver.aop;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.orderserver.client.UserFeign;
import com.example.userserver.enums.ReturnEnum;
import com.example.userserver.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * Aop 登录拦截器
 */
@Slf4j
@Aspect
@Component
public class HttpAspect {
    @Autowired
    private UserFeign userFeign;
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class);
    /**
     * @Pointcut 声明切入点表达式。
     * 注意此处扫描的是你的Controller层接口位置
     */
    @Pointcut("execution(public * com.example.orderserver.controller..*..*(..))")
    public void pointcut() {
    }

    /**
     * @Around 环绕通知
     * @Around("pointcut()") 可以理解为对这个方法进行环绕通知
     * ProceedingJoinPoint 参数 用于环绕通知，
     * 使用proceed()方法来执行目标方法，可以理解为 前置通知结束 开始执行使用该注解的方法。
     */
    @Around("pointcut()")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("Authorization");

        if (StringUtils.isNotBlank(token)) {
            if(!userFeign.check(token)){
                LOGGER.info("用户token错误，token：" + token);
                return new Result(null, ReturnEnum.TOKEN_WRONG);
            }
        }
        else {
            LOGGER.info("用户token为空");
            return new Result(null, ReturnEnum.TOKEN_LACK);
        }
        //执行业务逻辑，放行
        return joinPoint.proceed();
    }
}